package com.passer.toolbox.common.core.util;

import com.passer.toolbox.common.core.lang.UUID;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public class UUIDUtils {

    public static String fastUUID() {
        return randomUUID(false).toString();
    }

    public static String randomUUID() {
        return randomUUID(true).toString();
    }

    public static UUID randomUUID(boolean isSecure) {
        Random ng = isSecure ? new SecureRandom() : ThreadLocalRandom.current();
        byte[] randomBytes = new byte[16];
        ng.nextBytes(randomBytes);
        randomBytes[6] = (byte)(randomBytes[6] & 15);
        randomBytes[6] = (byte)(randomBytes[6] | 64);
        randomBytes[8] = (byte)(randomBytes[8] & 63);
        randomBytes[8] = (byte)(randomBytes[8] | 128);
        return new UUID(randomBytes);
    }

    public static UUID nameUUIDFromBytes(byte[] name) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException var3) {
            throw new InternalError("MD5 not supported");
        }

        byte[] md5Bytes = md.digest(name);
        md5Bytes[6] = (byte)(md5Bytes[6] & 15);
        md5Bytes[6] = (byte)(md5Bytes[6] | 48);
        md5Bytes[8] = (byte)(md5Bytes[8] & 63);
        md5Bytes[8] = (byte)(md5Bytes[8] | 128);
        return new UUID(md5Bytes);
    }

    public static UUID fromString(String name) {
        String[] components = name.split("-");
        if (components.length != 5) {
            throw new IllegalArgumentException("Invalid UUID string: " + name);
        } else {
            for(int i = 0; i < 5; ++i) {
                components[i] = "0x" + components[i];
            }

            long mostSigBits = Long.decode(components[0]);
            mostSigBits <<= 16;
            mostSigBits |= Long.decode(components[1]);
            mostSigBits <<= 16;
            mostSigBits |= Long.decode(components[2]);
            long leastSigBits = Long.decode(components[3]);
            leastSigBits <<= 48;
            leastSigBits |= Long.decode(components[4]);
            return new UUID(mostSigBits, leastSigBits);
        }
    }
}
